home *** CD-ROM | disk | FTP | other *** search
-
-
- program Backup;
-
- {------------------------------------------------------------------------------
-
- Backup is a program that writes a batch file that copies new files
- from an original to a backup disk. It uses MSDOS function calls(described
- in the DOS Technical Reference Manual) to extract the file names from the
- disk directory of the original disk. The filenames are stored in an array,
- and checked against the directory of the backup disk to see if they already
- exist. If a file does not exist on the backup disk then the file name is
- written to a DOS batch file with the appropriate 'COPY' command format.
- The major part of this program was adapted from the sample TURBO
- PASCAL program 'QDL'. The modifications and additions were made by Al Wang,
- Children's Hospital Research Foundation, Cincinnati,Ohio 45229
-
- ------------------------------------------------------------------------------}
- {$I-,U-,C-}
-
-
- type { TYPE declarations }
- Registers =
- record { register pack used in MSDos call }
- AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
- end;
- Char80arr = array [ 1..80 ] of Char;
- String80 = string[ 80 ];
- filename = string[14];
-
- var { VARIABLE declarations }
- DTA : array [ 1..43 ] of Byte; { Data Transfer Area Buffer }
- DTAseg, { DTA Segment before exicution }
- DTAofs, { DTA Offset " " }
- SetDTAseg, { DTA Segment and Offset set after }
- SetDTAofs, { start of program }
- Error, { Error return }
- Stop, { Returns the number of files }
- I, J,index, { used as counters }
- Option : Integer; { used to specify file types }
- Regs : registers; { register pack for the DOS call }
- Buffer, { generic Buffer }
- NamR : String80; { file name }
- Mask : Char80arr; { file Mask }
- Fname: filename; { file name }
- Backup : Text; { output batch file }
- Dir : array [1..512] of filename; { array of file names }
- source,dest : string[2]; { drive specifications}
-
- {------------------------------------------------------------------------------
- SetDTA resets the current DTA to the new address specified in the
- parameters 'SEGMENT' and 'OFFSET'.
- ------------------------------------------------------------------------------}
-
- procedure SetDTA( Segment, Offset : Integer; var Error : Integer );
- begin
- Regs.AX := $1A00; { Function used to set the DTA }
- Regs.DS := Segment; { store the parameter Segment in DS }
- Regs.DX := Offset; { " " " Offset in DX }
- MSDos( Regs ); { Set DTA location }
- Error := Regs.AX and $FF; { get Error return }
- end; { of proc SetDTA }
-
- {------------------------------------------------------------------------------
- GetCurrentDTA is used to get the current Disk Transfer Area ( DTA )
- address. A function code of $2F is stored in the high Byte of the AX
- register and a call to the predefined procedure MSDos is made. This can
- also be accomplished by using the "Intr" procedure with the same register
- record and a $21 specification for the interrupt.
- ------------------------------------------------------------------------------}
-
- procedure GetCurrentDTA( var Segment, Offset : Integer;
- var Error : Integer );
- begin
- Regs.AX := $2F00; { Function used to get current DTA address }
- { $2F00 is used instead of $2F shl 8 to save
- three assembly instructions. An idea for
- optimization. }
- MSDos( Regs ); { Exicute MSDos function request }
- Segment := Regs.ES; { Segment of DTA returned by DOS }
- Offset := Regs.BX; { Offset of DTA returned }
- Error := Regs.AX and $FF;
- end; { of proc GetCurrentDTA }
-
-
- {------------------------------------------------------------------------------
- GetFirst gets the first directory entry of a particular file Mask. The
- Mask is passed as a parameter 'Mask' and, the Option was previosly specified
- in the SpecifyOption procedure.
- ------------------------------------------------------------------------------}
-
- procedure GetFirst( Mask : Char80arr; var NamR : String80;
- Segment, Offset : Integer; Option : Integer;
- var Error : Integer );
- var
- I : Integer;
- begin
- Error := 0;
- Regs.AX := $4E00; { Get first directory entry }
- Regs.DS := Seg( Mask ); { Point to the file Mask }
- Regs.DX := Ofs( Mask );
- Regs.CX := Option; { Store the Option }
- MSDos( Regs ); { Exicute MSDos call }
- Error := Regs.AX and $FF; { Get Error return }
- I := 1; { initialize 'I' to the first element }
- repeat { Enter the loop that reads in the }
- { first file entry }
- NamR[ I ] := Chr( mem[ Segment : Offset + 29 + I ] );
- I := I + 1;
- until ( not ( NamR[ I - 1 ] in [ ' '..'~' ] ));
- NamR[ 0 ] := Chr( I - 1 ); { set string length because assigning }
- { by element does not set length }
- end; { of proc GetFirst }
-
- {------------------------------------------------------------------------------
- GetNextEntry uses the first bytes of the DTA for the file Mask, and
- returns the next file entry on disk corresponding to the file Mask.
- ------------------------------------------------------------------------------}
-
- procedure GetNextEntry( var NamR : String80; Segment, Offset : Integer;
- Option : Integer; var Error : Integer );
- var
- I : Integer;
- begin
- Error := 0;
- Regs.AX := $4F00; { Function used to get the next }
- { directory entry }
- Regs.CX := Option; { Set the file option }
- MSDos( Regs ); { Call MSDos }
- Error := Regs.AX and $FF; { get the Error return }
- I := 1;
- repeat
- NamR[ I ] := Chr( mem[ Segment : Offset + 29 + I ] );
- I := I + 1;
- until ( not ( NamR[ I - 1 ] in [ ' '..'~' ] ));
- NamR[ 0 ] := Chr( I - 1 );
- end; { of proc GetNextEntry }
-
- {-----------------------------------------------------------------------------
-
- This function determines if a given file name exists. The file name may
- include drive specifications and wildcards. This function was taken from
- page 96 of the TURBO PASCAL reference manual.
-
- ------------------------------------------------------------------------------}
-
- function Exist(Filname: filename): Boolean;
- var
- Fil:file;
- begin
- Assign(Fil,Filname);
- {$I-}
- Reset(Fil);
- {$I+}
- Exist:=(IOresult=0)
- end; { of Exist }
-
- {
- main body of program QDL
- }
-
- begin
- write('Enter source drive specification(letter, colon, enter):');
- readln(source);
- write('Enter destination drive specification(letter, colon, enter):');
- readln(dest);
- Assign(Backup,'TRANSFER.BAT');
- Rewrite(Backup);
- index:=2;
- for I := 1 to 512 do dir[ I ] :='';
- for I := 1 to 21 do DTA[ I ] := 0; { Initialize the DTA Buffer }
- for I := 1 to 80 do begin { Initialize the Mask and }
- Mask[ I ] := Chr( 0 ); { file name buffers }
- NamR[ I ] := Chr( 0 );
- end;
- NamR[ 0 ] := Chr( 0 ); { Set the file name length to 0 }
- GetCurrentDTA( DTAseg, DTAofs, Error ); { Get the current DTA address }
- if ( Error <> 0 ) then begin { Check for errors }
- WriteLn( 'Unable to get current DTA' );
- WriteLn( 'Program aborting.' ); { and abort. }
- Halt; { end program now }
- end;
- SetDTAseg := Seg( DTA );
- SetDTAofs := Ofs( DTA );
- SetDTA( SetDTAseg, SetDTAofs, Error ); { Reset DTA addresses }
- if ( Error <> 0 ) then begin { Check for errors }
- WriteLn( 'Cannot reset DTA' ); { Error message }
- WriteLn( 'Program aborting.' );
- Halt; { end program }
- end;
- Error := 0;
- Buffer[ 0 ] := Chr( 0 ); { Set Buffer length to 0 }
- Option:=4; { Get file Option }
- Buffer:=source+'????????.???';
- for I := 1 to length( Buffer ) do { Assign Buffer to Mask }
- Mask[ I ] := Buffer[ I ];
- GetFirst( Mask, NamR, SetDTAseg, SetDTAofs, Option, Error );
- if ( Error = 0 ) then begin { Get the first directory entry }
- dir[1]:=NamR;
- end
- else WriteLn( 'File ''', Buffer, ''' not found.' );
- while ( Error = 0 ) do begin
- GetNextEntry( NamR, SetDTAseg, SetDTAofs, Option, Error );
- if ( Error = 0 ) then
- dir[index]:=NamR;
- index:=index+1;
- Stop:=index;
- end;
- for index:= 1 to Stop do begin
- if ( dir[index]<> '' ) then begin
- Fname:=dest+dir[index];
- if not Exist(Fname) then
- writeln(Backup,'COPY '+source+dir[index]+' '+dest);
- end;
- end;
- SetDTA( DTAseg, DTAofs, Error );
- Close(Backup);
- end. { end Main }
-
-